home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1990 by Christopher A. Wichura.
- See file GIFMachine.doc for full description of rights.
- */
-
- #include "GIFMachine.h"
-
- extern struct GIFdescriptor gdesc;
- EXTERNBITPLANE;
-
- extern BOOL DisplayCounts;
-
- /* since both MasterColourTable and the PaletteBuf are the same size and
- type we will define MCT to be the PaletteBuf to cut down on static
- memory declarations */
- #define MasterColourTable PaletteBuf
-
- extern UBYTE MasterColourTable[MAXCOLOURS];
- static UWORD TotalColours;
-
- extern BYTE *CurrentLineErr[3];
- extern BYTE *LastLineErr[3];
-
- extern char *AbortMsg;
-
- #define MAXERR 2
-
- void ReduceTo12(void)
- {
- register UWORD x;
- register UWORD y;
-
- PutStr("...Reducing palette to 12 bits.\n......");
- if (DisplayCounts)
- PutStr("Line ");
- else
- PutStr("Working");
- Flush(Output());
-
- TotalColours = 0;
- memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
-
- for (y = 0; y < gdesc.gd_Height; y++) {
- if (DisplayCounts)
- MyPrintf("%5ld", y);
-
- if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
- MyPrintf("\n%s", AbortMsg);
- MyExit(ABORTEXITVAL);
- }
-
- for (x = 0; x < gdesc.gd_Width; x++)
- PutValue(x, y, AddColour(&BitPlane[y][x]));
-
- if (DisplayCounts)
- PutStr("\x1B[5D");
- }
-
- MyPrintf("\x1B[%ldD%ld total unique colours used.\n", (DisplayCounts ? 5 : 7), TotalColours);
- }
-
- void DitherTo12(void)
- {
- register UWORD x;
- register UWORD y;
- register int RedErr;
- register int GreenErr;
- register int BlueErr;
- BYTE **cerr, **lerr, **terr;
- struct RGB rgb;
-
- PutStr("...Dithering palette to 12 bits.\n......Setup");
- Flush(Output());
-
- TotalColours = 0;
- memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
-
- cerr = (BYTE **)&CurrentLineErr[0];
- lerr = (BYTE **)&LastLineErr[0];
-
- /* the top, left and right borders will be used unmodified */
-
- for (x = 0; x < gdesc.gd_Width; x++)
- PutValue(x, 0, AddColour(&BitPlane[0][x]));
-
- for (y = 1; y < gdesc.gd_Height; y++) {
- PutValue(0, y, AddColour(&BitPlane[y][0]));
- PutValue(gdesc.gd_Width - 1, y, AddColour(&BitPlane[y][gdesc.gd_Width - 1]));
- }
-
- /* since the error tables are alloced with MEMF_CLEAR we won't bother
- to clear them here. instead, we just hit the main loop */
-
- if (DisplayCounts)
- PutStr("\x1B[5DLine ");
- else
- PutStr("\x1B[5DWorking");
- Flush(Output());
-
- for (y = 1; y < gdesc.gd_Height; y++) {
- if (DisplayCounts)
- MyPrintf("%5ld", y);
-
- if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
- MyPrintf("\n%s", AbortMsg);
- MyExit(ABORTEXITVAL);
- }
-
- for (x = 1; x < (gdesc.gd_Width - 1); x++) {
- rgb = BitPlane[y][x];
-
- RedErr = cerr[0][x - 1] + 7*lerr[0][x - 1] + 5*lerr[0][x] + 3*lerr[0][x + 1];
- GreenErr = cerr[1][x - 1] + 7*lerr[1][x - 1] + 5*lerr[1][x] + 3*lerr[1][x + 1];
- BlueErr = cerr[2][x - 1] + 7*lerr[2][x - 1] + 5*lerr[2][x] + 3*lerr[2][x + 1];
-
- RedErr >>= 4;
- GreenErr >>= 4;
- BlueErr >>= 4;
-
- /* now we add the errors into the colour we want. if this would push
- us over 255 (and thus out of range) we subtract the error out so
- that we still see some dithering instead of washing out the area. */
-
- if (rgb.rgb_Red + RedErr > 255)
- rgb.rgb_Red -= RedErr;
- else
- rgb.rgb_Red += RedErr;
-
- if (rgb.rgb_Green + GreenErr > 255)
- rgb.rgb_Green -= GreenErr;
- else
- rgb.rgb_Green += GreenErr;
-
- if (rgb.rgb_Blue + BlueErr > 255)
- rgb.rgb_Blue -= BlueErr;
- else
- rgb.rgb_Blue += BlueErr;
-
- PutValue(x, y, AddColour(&rgb));
-
- RedErr = (int)rgb.rgb_Red - (int)(rgb.rgb_Red & 0xF0);
- GreenErr = (int)rgb.rgb_Green - (int)(rgb.rgb_Green & 0xF0);
- BlueErr = (int)rgb.rgb_Blue - (int)(rgb.rgb_Blue & 0xF0);
-
- if (RedErr > MAXERR)
- RedErr = (RedErr * 3) >> 2;
-
- if (GreenErr > MAXERR)
- GreenErr = (GreenErr * 3) >> 2;
-
- if (BlueErr > MAXERR)
- BlueErr = (BlueErr * 3) >> 2;
-
- cerr[0][x] = RedErr;
- cerr[1][x] = GreenErr;
- cerr[2][x] = BlueErr;
- }
-
- terr = lerr;
- lerr = cerr;
- cerr = terr;
-
- if (DisplayCounts)
- PutStr("\x1B[5D");
- }
-
- MyPrintf("\x1B[%ldD%ld total unique colours used.\n", (DisplayCounts ? 5 : 7), TotalColours);
- }
-
- UWORD AddColour(struct RGB *rgb)
- {
- register UWORD colour;
-
- colour = ((rgb->rgb_Red << 4) & 0xF00) |
- (rgb->rgb_Green & 0xF0) |
- (rgb->rgb_Blue >> 4);
-
- if (!MasterColourTable[colour]) {
- MasterColourTable[colour] = 1;
- TotalColours++;
- }
-
- return colour;
- }
-